#pragma once
#include <DataCore/sim_data.h>

namespace PhysLeo
{

/**
 * FixedFreedom cpu module
 */
template<typename T>
class FixedFreedomCpu
{
public:
    /**
     * empty constructor
     */
    FixedFreedomCpu() = default;

    /**
     * delete default copy constructor
     */
    FixedFreedomCpu(const FixedFreedomCpu<T>&) = delete;

    /**
     * delete default move constructor
     */
    FixedFreedomCpu(FixedFreedomCpu<T>&&) = delete;

    /**
     * delete default copy assignment function
     */
    FixedFreedomCpu<T>& operator=(const FixedFreedomCpu<T>&) = delete;

    /**
     * delete default move assignment function
     */
    FixedFreedomCpu<T>& operator=(FixedFreedomCpu<T>&&) = delete;

    /**
     * virtual destructor
     */
    virtual ~FixedFreedomCpu() = default;

    /**
     * allocate resource for fixed freedom module
     * @param simData  simulation data
     */
    virtual void allocateResource(SimData<T>& simData);

    /**
     * set the fixed Freedom of vec to zeros
     * @param vec  shared_ptr to vector buffer data which need to be set to zero on some positions
     */
    virtual void clearFixedFreedom(std::shared_ptr<BufferData<glm::tvec3<T>>> vec);

    /**
     * set specific value for the fixed Freedom of vec
     * @param vec  shared_ptr to vector buffer data which need to be set to zero on some positions
     * @param value  shared_ptr to value buffer data which stores the target value of fixed freedoms
     */
    virtual void setFixedFreedom(std::shared_ptr<BufferData<glm::tvec3<T>>> vec, std::shared_ptr<BufferData<T>> value);

protected:
    /**
     * fixed freedom. usually every point has x y z three freedoms
     */
    std::shared_ptr<BufferData<int>> ptr_fix_;
};

}